﻿using System.Text;

namespace WpInsights.Core
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    class ExceptionEvent
    {
        private static string DataItemCollection { get; set; }
        
        static ExceptionEvent()
        {
            DataItemCollection = ResourceReader.ReadToEnd("DataItemCollection.xml");
        }

        public static OperationsData GetDataItems(List<StackTraceRecord> stackTraceRecords)
        {
            var result = new OperationsData();
            var groupByApplication = new Dictionary<string, List<StackTraceRecord>>();
            foreach (var stackTraceRecord in stackTraceRecords)
            {
                if (!groupByApplication.ContainsKey(stackTraceRecord.App))
                {
                    groupByApplication.Add(stackTraceRecord.App, new List<StackTraceRecord>());
                }

                groupByApplication[stackTraceRecord.App].Add(stackTraceRecord);
            }

            foreach (var stackTraceRecord in stackTraceRecords)
            {
                var sb = new StringBuilder();
                sb.AppendFormat("<DataItems MachineName=\"Windows Phone {0}.{1}\">", stackTraceRecord.OsVersion.Major, stackTraceRecord.OsVersion.Minor);
                Console.WriteLine(DateTime.Now.ToString() + ": Procesing {1} {0} events", stackTraceRecord.ExceptionType, stackTraceRecord.CrashCount30Day);
                for (int i = 0; i < stackTraceRecord.CrashCount30Day; i++)
                {
                    var dataItem = GetDataItem(stackTraceRecord, stackTraceRecord.App);
                    sb.Append(dataItem);
                }
                sb.Append("</DataItems>");
                result.DataItemCollections.Add(sb.ToString());
            }

            foreach (var group in groupByApplication)
            {
                 string appName = group.Key;
                 result.Applications.Add(appName);
            }

            return result;
        }

        private static string GetDataItem(StackTraceRecord stackTraceRecord, string appName)
        {
            string result = DataItemCollection;
            result = result.Replace("{ExceptionType}", stackTraceRecord.ExceptionType);
            result = result.Replace("{UniqueId}", Guid.NewGuid().ToString());
            result = result.Replace("{UtcLogDate}", DateTime.UtcNow.ToString("s"));
            result = result.Replace("{EventSource}", appName);
            result = result.Replace("{AppVersion}", stackTraceRecord.AppVersion.ToString());
            result = result.Replace("{OsVersion}", stackTraceRecord.OsVersion.ToString(2));
            
            foreach (var stackPoint in stackTraceRecord.StackTrace.Items)
            {
                stackPoint.OnBeforeSerialize();
            }

            var stack = stackTraceRecord.StackTrace.SerializeObject();
            result = result.Replace("{Stack}", stack);

            var modules = GetModuleSection(stackTraceRecord);
            result = result.Replace("{Modules}", modules);
            return result;
        }

        public static string GetModuleSection(StackTraceRecord stackTraceRecord)
        {
            var modules = new ModuleList();
            foreach (var stackPoint in stackTraceRecord.StackTrace.Items)
            {
                if (!modules.Items.Exists(x => x.Name == stackPoint.Image))
                {
                    modules.Items.Add(new Module(stackTraceRecord.OsVersion) { Name = stackPoint.Image });
                }
            }

            return modules.SerializeObject();
        }
    }
}
